package com.technique.api.util;

import java.util.Calendar;
import java.util.concurrent.atomic.AtomicLong;

/**
 * 
 * @author chenfei3 2013-6-4
 */
public class RequestTraceContext {
    private static final ThreadLocal<RequestTraceContext> requestContext = new ThreadLocal<RequestTraceContext>();
    private static final AtomicLong idGenerator = new AtomicLong();
    private static long refreshIdPrefix = 0;

    private long id;
    private String requestId;
    
    static {
    	int intIp = IPUtils.ipToInt(IPUtils.getLocalIp());
    	intIp = intIp & 0x00FFFFFF;
    	intIp <<= 6;
    	
		int minute=Calendar.getInstance().get(Calendar.MINUTE);	//获取当前的分钟数
		
		refreshIdPrefix = ((long)(intIp | minute)) << 33;
    }
    
    public RequestTraceContext(){
        this.id = refreshIdPrefix | idGenerator.incrementAndGet();
        this.requestId = String.valueOf(id);
    }
    
    public RequestTraceContext(String api, long uid, String appKey, int appId, String originalSource) {
        this.id = refreshIdPrefix | idGenerator.incrementAndGet();
    }
    
    public static void init(){
    	requestContext.set(new RequestTraceContext());
    }

    /**
     * set current thread context according to parent thread context.
     * 
     * @param parentContext
     */
    public static void spawn(RequestTraceContext parentContext) {
        requestContext.set(parentContext);
    }

    /**
     * clear current thread context, which may leads to {@link #get()} return
     * null.
     */
    public static void clear() {
        requestContext.remove();
    }

    /**
     * get current thread's context. the context may be initialized by parent
     * thread or explicit call {@link #init(String)}
     * 
     * @return null if current thread doesn't have any context.
     */
    public static RequestTraceContext get() {
        return requestContext.get();
    }

    /**
     * 
     */
    public static void finish() {
        clear();
    }
    
    public static String getRequestId() {
    	RequestTraceContext context = get();
        if (context != null) {
        	return context.requestId;
        }
        return null;
    }
    
    
}
